/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package project.jpdftools.imagemerger.thread;

import java.io.File;
import java.util.logging.Level;
import javax.swing.DefaultListModel;
import javax.swing.JOptionPane;
import project.jpdfexport.tools.ImageMergerManager;
import project.jpdftools.animation.AnimationWorker;
import project.jpdftools.animation.AnimationWorkerThread;
import project.jpdftools.constants.Const;
import project.jpdftools.imagemerger.compress.CompressImage;
import project.jpdftools.managers.LocalizationManager;
import project.jpdftools.managers.LoggerManager;
import project.jpdftools.other.JOpenFile;
import project.jpdftools.other.KeyValue;

/**
 *
 * @author Mido
 */
public class ImageMergerThread extends AnimationWorkerThread {

    private DefaultListModel defaultModel;
    private boolean compressImages;
    private String title;
    private String author;
    private String subject;
    private String keyWords;
    private File selectedFile;

    public ImageMergerThread(AnimationWorker AnimationWorker, boolean compressImages, String title, String author, String subject, String keyWords,
            File selectedFile, DefaultListModel defaultModel) {
        super(AnimationWorker);
        this.compressImages = compressImages;
        this.title = title;
        this.author = author;
        this.subject = subject;
        this.keyWords = keyWords;
        this.selectedFile = selectedFile;
        this.defaultModel = defaultModel;
    }

    @Override
    public void run() {
        // start the animation
        this.getAnimationWorker().execute();

        int list_size = defaultModel.getSize();
        String[] list = new String[list_size];
        // get data from source pdfs
        // check first for compression enabled or not
        if (compressImages == true) {
            for (int i = 0; i < list_size; i++) {
                // compress each file
                list[i] = CompressImage.compress(((KeyValue) defaultModel.getElementAt(i)).getKey(), "Data/Working Directory");
                if (list[i].isEmpty() == true) {
                    // compression falied. use the original images
                    list[i] = ((KeyValue) defaultModel.getElementAt(i)).getKey();
                }
            }
        } else {
            for (int i = 0; i < list_size; i++) {
                list[i] = ((KeyValue) defaultModel.getElementAt(i)).getKey();
            }
        }

        // pass the parameters to the merge class
        ImageMergerManager merge_files = new ImageMergerManager(list, selectedFile.toString());
        boolean result = merge_files.merge(Const.program_version, title, author, subject, keyWords);

        // kill the animation thread
        this.getAnimationWorker().setKillSignal(true);

        // set operation result and finalize
        // must be executed in the EventDispatchThread
        final boolean operationResult = result;
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                if (operationResult == true) {
                    Object[] options = {LocalizationManager.getCurrent_resource().getString("OPEN_FILE"),
                        LocalizationManager.getCurrent_resource().getString("DONT_OPEN_FILE")};

                    // ask the user if he/she wants to open the merged file
                    if (compressImages == true) {
                        JOpenFile.showOptionDialog(LocalizationManager.getCurrent_resource().getString("MERGE_FILES_PANEL_COMPRESSION_SUCCESS") + " "
                                + getCompressionRatio(getListOfFiles(), selectedFile.toString() + ".pdf") + " %)\n"
                                + LocalizationManager.getCurrent_resource().getString("MERGE_FILES_PANEL_OPEN_FILE_QUESTION"),
                                LocalizationManager.getCurrent_resource().getString("SUCCESS"), options, selectedFile + ".pdf");
                    } else {
                        JOpenFile.showOptionDialog(LocalizationManager.getCurrent_resource().getString("MERGE_FILES_PANEL_SUCCESS"),
                                LocalizationManager.getCurrent_resource().getString("SUCCESS"), options, selectedFile + ".pdf");
                    }
                    LoggerManager.getLogger().log(Level.INFO, "Images merged successfully.");
                } else {
                    // show error message
                    JOptionPane.showMessageDialog(null, LocalizationManager.getCurrent_resource().getString("MERGE_FILES_PANEL_FAIL"),
                            LocalizationManager.getCurrent_resource().getString("ERROR"), 0);
                    LoggerManager.getLogger().log(Level.SEVERE, "Merging images failed.");
                }
            }
        });

        // clear the working directory after finishing
        File[] files = new File("Data/Working Directory").listFiles();
        for (File in : files) {
            in.deleteOnExit();
        }
    }

    /**
     * Calculates the compression ration of the list of files passed on the file
     * size
     *
     * @param list the list of input files
     * @param outFile the output file
     * @return
     */
    private String getCompressionRatio(String[] list, String outFile) {
        long input_size = 0;
        long output_size = 0;
        // calculate input files size
        for (int i = 0; i < list.length; i++) {
            input_size += new File(list[i]).length();
        }
        // calculate output file size
        output_size = new File(outFile).length();

        // calculate the compression ratio
        long difference = Math.abs(input_size - output_size);
        double div = (double) difference / (double) input_size;
        return String.valueOf((float) div * 100);
    }

    /**
     * Return a list of all the files required to be merged
     *
     * @return
     */
    private String[] getListOfFiles() {
        String[] list = new String[defaultModel.getSize()];
        for (int i = 0; i < list.length; i++) {
            list[i] = ((KeyValue) defaultModel.getElementAt(i)).getKey();
        }
        return list;
    }
}
